package redisdemo;


import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.redis.core.BoundListOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:application-redis.xml")
public class ListRedisTest {

    @Resource
    RedisTemplate redisTemplate;

    ListOperations listOperations;

    @Before
    public void load(){
        listOperations = redisTemplate.opsForList();
    }

    //List<V> range(K key, long start, long end);
    //返回存储在键中的列表的指定元素。偏移开始和停止是基于零的索引，其中0是列表的第一个元素（列表的头部），1是下一个元素
    public void range(){
        List list = listOperations.range("list", 0, -1);
        System.out.println(list);
    }

    //将所有指定的值插入存储在键的列表的头部。如果键不存在，则在执行推送操作之前将其创建为空列表
    @Test
    public void Push(){
        // Long leftPush(K key, V value);
        // （从左边插入）
        listOperations.leftPush("list","python");
        listOperations.leftPush("list","c++");

        // Long rightPush(K key, V value);
        // （从右边插入）
        listOperations.rightPush("list","java");

        //Long leftPushAll(K key, Collection<V> values);
        //Long leftPushAll(K key, V... values);
        //批量把一个集合|数组插入到列表中
        listOperations.leftPushAll("sea",new String[]{"fish","shrimp","crab"});
        System.out.println(listOperations.range("list",0,-1));
        System.out.println(listOperations.range("sea",0,-1));
    }

    /**
     * Long leftPushIfPresent(K key, V value);
     * 只有存在key对应的列表才能将这个value值插入到key所对应的列表中
     */
    @Test
    public void leftPushIfPresent(){
        String [] list = new String[]{"1","2","3"};
        System.out.println(listOperations.leftPushIfPresent("left","1"));//结果：0
    }

    //Long size(K key);
    //返回存储在键中的列表的长度。如果键不存在，则将其解释为空列表，并返回0。当key存储的值不是列表时返回错误。
    @Test
    public void size(){
        BoundListOperations sea = redisTemplate.boundListOps("sea");
        System.out.println(sea.size());
    }

    //V index(K key, long index);
    //根据下表获取列表中的值，下标是从0开始的
    public void index(){
        BoundListOperations sea = redisTemplate.boundListOps("sea");
        System.out.println(sea.index(1));
    }

    /**
     * void trim(K key, long start, long end);
     * 修剪现有列表，使其只包含指定的指定范围的元素，起始和停止都是基于0的索引
     * 从start 索引数开始，到end 索引数修剪，其他的全删除
     */
    @Test
    public void trim(){
        BoundListOperations sea = redisTemplate.boundListOps("sea");
        System.out.println(sea.range(0,-1));
        sea.trim(1,7);  //下标1-7的7个元素外全删除
        System.out.println(sea.range(0,-1));
        sea.trim(1,6);  //下标1-6的6个元素外全删除
        System.out.println(sea.range(0,-1));
        sea.trim(1,4);  //类推
        System.out.println(sea.range(0,-1));
        sea.trim(1,3);
        System.out.println(sea.range(0,-1));
        sea.trim(1,1);
        System.out.println(sea.range(0,-1));
    }

    /**
     * Long remove(K key, long count, Object value);
     * 从存储在键中的列表中删除等于值的元素的第一个计数事件。
     * 计数参数以下列方式影响操作：
     * count> 0：删除等于从头到尾移动的值的元素。(左往右 第一个
     * count <0：删除等于从尾到头移动的值的元素。(右往左 第一个
     * count = 0：删除等于value的所有元素。
     */
    @Test
    public void removeListTest(){
        System.out.println(listOperations.range("sea",0,-1));
        listOperations.remove("sea",1,"shrimp");
        System.out.println(listOperations.range("sea",0,-1));
    }

    //V leftPop(K key);
    //弹出最左边的元素，弹出之后该值在列表中将不复存在
    public void leftPop(){
        BoundListOperations sea = redisTemplate.boundListOps("sea");
        System.out.println(sea.leftPop());
        //-----分割线------
        System.out.println(redisTemplate.opsForList().leftPop("sea"));
    }
}
